package pers.amos.eshop.advance.data.aggregation.mq;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.json.JSONObject;
import cn.hutool.log.StaticLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import pers.amos.eshop.advance.data.aggregation.common.DimTypeConstants;
import pers.amos.eshop.advance.data.aggregation.redis.RedisUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author amos wong
 * @create 2020-12-17 11:50 上午
 */
@Component
public class BaseQueueReceiver {

    @Autowired
    private RedisUtils redisUtils;

    private static final String BRAND_PREFIX_KEY = "brand_";
    private static final String CATEGORY_PREFIX_KEY = "category_";
    private static final String PRODUCT_INTRO_PREFIX_KEY = "product_intro_";
    private static final String PRODUCT_PROPERTY_PREFIX_KEY = "brand_property_";
    private static final String PRODUCT_PREFIX_KEY = "product_";
    private static final String PRODUCT_SPECIFICATION_PREFIX_KEY = "product_specification_";

    public void aggregationData(String message) {
        StaticLog.info("【数据聚合服务】，收到了一条数据聚合的消息：{}", message);

        JSONObject jsonObject = new JSONObject(message);
        String dimType = (String) jsonObject.get("dim_type");
        Long id = Convert.toLong(jsonObject.get("id"));

        switch (dimType) {
            case DimTypeConstants.BRAND_DIM_TYPE:
                aggregationBrandData(id);
                break;
            case DimTypeConstants.CATEGORY_DIM_TYPE:
                aggregationCategoryData(id);
                break;
            case DimTypeConstants.PRODUCT_DIM_TYPE:
                aggregationProductData(id);
                break;
            default:
                aggregationProductIntroData(id);
                break;
        }
    }

    private void aggregationBrandData(Long id) {
        String brand = redisUtils.get(BRAND_PREFIX_KEY + id);
        redisUtils.set("dim_brand_" + id, brand);

        StaticLog.info("【数据聚合服务】品牌数据聚合完成，brandId = {}", id);
    }

    private void aggregationCategoryData(Long id) {
        String category = redisUtils.get(CATEGORY_PREFIX_KEY + id);
        redisUtils.set("dim_category_" + id, category);

        StaticLog.info("【数据聚合服务】分类数据聚合完成，categoryId = {}", id);
    }

    /**
     * 进行数据聚合
     * 针对于 dim_product、product_intro 类型的数据 这里的 id 为 productId
     * 针对于 brand、category 类型的数据这里的 id 为其主键
     *
     * @param id
     */
    private void aggregationProductData(Long id) {
        JSONObject jsonObject = new JSONObject();

        // 使用 mget 批量查询来优化性能
        ArrayList<String> keys = CollUtil.newArrayList(PRODUCT_PREFIX_KEY + id,
                PRODUCT_PROPERTY_PREFIX_KEY + id, PRODUCT_SPECIFICATION_PREFIX_KEY + id);
        List<String> result = redisUtils.mget(keys);

        if (CollUtil.isNotEmpty(result) && !StringUtils.isEmpty(result.get(0))) {
            String product = result.get(0);
            jsonObject.set("product", product);

            String productProperty = result.get(1);
            if (!StringUtils.isEmpty(productProperty)) {
                jsonObject.set("product_property", productProperty);
            }

            String productSpecification = result.get(2);
            if (!StringUtils.isEmpty(productSpecification)) {
                jsonObject.set("product_specification", productSpecification);
            }

            redisUtils.set("dim_product_" + id, jsonObject.toString());

            StaticLog.info("【数据聚合服务】商品主属性数据聚合完成，productId = {}", id);
        } else {
            redisUtils.delete("dim_product_" + id);
        }
    }

    private void aggregationProductIntroData(Long id) {
        String productIntro = redisUtils.get(PRODUCT_INTRO_PREFIX_KEY + id);
        redisUtils.set("dim_product_intro_" + id, productIntro);

        StaticLog.info("【数据聚合服务】商品描述数据聚合完成，productId = {}", id);
    }
}
